////////////////////////////////////////////////////////////////////////////////
/// @file     tim3_pwm_output.c
/// @author   AE TEAM
/// @brief    PWM output.
////////////////////////////////////////////////////////////////////////////////
/// @attention
///
/// THE EXISTING FIRMWARE IS ONLY FOR REFERENCE, WHICH IS DESIGNED TO PROVIDE
/// CUSTOMERS WITH CODING INFORMATION ABOUT THEIR PRODUCTS SO THEY CAN SAVE
/// TIME. THEREFORE, MINDMOTION SHALL NOT BE LIABLE FOR ANY DIRECT, INDIRECT OR
/// CONSEQUENTIAL DAMAGES ABOUT ANY CLAIMS ARISING OUT OF THE CONTENT OF SUCH
/// HARDWARE AND/OR THE USE OF THE CODING INFORMATION CONTAINED HEREIN IN
/// CONNECTION WITH PRODUCTS MADE BY CUSTOMERS.
///
/// <H2><CENTER>&COPY; COPYRIGHT MINDMOTION </CENTER></H2>
////////////////////////////////////////////////////////////////////////////////
// Define to prevent recursive inclusion
#define _TIM3_PWM_OUTPUT_C_

// Files includes
#include "mm32_device.h"
#include "hal_conf.h"
#include "tim3_pwm_output.h"


////////////////////////////////////////////////////////////////////////////////
/// @addtogroup MM32_Hardware_Abstract_Layer
/// @{

////////////////////////////////////////////////////////////////////////////////
/// @addtogroup TIM3_PWM_OUTPUT
/// @{

////////////////////////////////////////////////////////////////////////////////
/// @addtogroup TIM_Exported_Functions
/// @{
////////////////////////////////////////////////////////////////////////////////
/// @brief  Setup this IP clock
/// @note   This function should affected by chip version.
/// @param  TIMx : Select TIM port.
/// @param  NewState : Enable or disable the IP clock.
/// @retval None.
////////////////////////////////////////////////////////////////////////////////
void CFG_TIM_Clock(TIM_TypeDef* TIMx, FunctionalState NewState)
{
    if      (TIMx == TIM1) {
        //CFG_IpClock(emIPCLOCK_TIM1,NewState);
        RCC_APB1PeriphClockCmd(RCC_APB1ENR_TIM1, NewState);
    }
    else if (TIMx == TIM3) {
        RCC_APB1PeriphClockCmd(RCC_APB1ENR_TIM3, NewState);
    }

    else if (TIMx == TIM14) {
        RCC_APB1PeriphClockCmd(RCC_APB1ENR_TIM14, NewState);
    }
}

////////////////////////////////////////////////////////////////////////////////
/// @brief  Timer Pin Config
/// @param  None
/// @retval None.
////////////////////////////////////////////////////////////////////////////////
static void TimerPinConfig(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;

    RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOA, ENABLE);
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource11, GPIO_AF_4);

    GPIO_InitStructure.GPIO_Pin  =  GPIO_Pin_11;                                //TIM3_CH1
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief  Time Base initialization configuration
/// @note
/// @param  psc: Clock frequency division value.
/// @param  arr: Preloading value.
/// @retval None.
////////////////////////////////////////////////////////////////////////////////
void Tim3InitSetting(u16 arr, u16 psc)
{
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;

    CFG_TIM_Clock(TIM3, ENABLE);

    TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
    TIM_TimeBaseStructure.TIM_Period = arr;
    TIM_TimeBaseStructure.TIM_Prescaler = psc;
    //Setting Clock Segmentation
    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
    ///TIM Upward Counting Mode
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief  Output compare initialization configuration
/// @note
/// @param
/// @retval None.
////////////////////////////////////////////////////////////////////////////////
void Tim3PwmOutputInitSetting(void)
{
    TIM_OCInitTypeDef  TIM_OCInitStructure;

    TIM_OCStructInit(&TIM_OCInitStructure);
    //Select Timer Mode: TIM Pulse Width Modulation Mode 2
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    //Setting the Pulse Value of the Capture Comparison Register to be Loaded
    TIM_OCInitStructure.TIM_Pulse = 0;
    //Output polarity: TIM output is more polar
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
    TIM_OC1Init(TIM3, &TIM_OCInitStructure);

    TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);
    TIM_ARRPreloadConfig(TIM3, ENABLE);
    TIM_CtrlPWMOutputs(TIM3, ENABLE);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief  timer enable
/// @note    If the program fails, see here.
/// @param  None.
/// @retval None.
////////////////////////////////////////////////////////////////////////////////
void TimerEnable(void)
{
    TIM_Cmd(TIM3, ENABLE);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief  Tim3 pwm output test
/// @param  None.
/// @retval None.
////////////////////////////////////////////////////////////////////////////////
void Tim3PwmOutputTest(void)
{
    TimerPinConfig();
    Tim3InitSetting(99, 0);
    Tim3PwmOutputInitSetting();
    TimerEnable();
}
/// @}


/// @}

/// @}



